home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-09-12 | 18.2 KB | 421 lines | [TEXT/CCL2] |
-
- (in-package :TRAPS) ; ***********************************************************
- ;
- ; Created: Sunday, February 7, 1993 at 4:54PM
- ; DigitalSignature.p
- ; Pascal Interface to the Macintosh Libraries
- ;
- ; ••• Apple Confidential •••
- ; ••• Provided with AOCE Beta seed under license agreement with •••
- ; ••• Apple Computer, Inc. Use for any purpose other than •••
- ; ••• development of AOCE-based Macintosh products is a violation •••
- ; ••• of the license agreement. •••
- ;
- ; Copyright Apple Computer, Inc. 1990-1993
- ; All rights reserved
- ;
- ; ***********************************************************
-
- ; $IFC UNDEFINED UsingIncludes
- ; $SETC UsingIncludes:= 0
- ; $ENDC
-
- ; $IFC NOT UsingIncludes
-
- ; $ENDC
-
- ; $IFC UNDEFINED UsingDigitalSignature
- ; $SETC UsingDigitalSignature:= 1
-
- ; $I+
- ; $SETC DigitalSignatureIncludes:= UsingIncludes
- ; $SETC UsingIncludes:= 1
-
- ; $IFC UNDEFINED UsingFiles
-
- (require-interface 'FILES) ; $I $$Shell(PInterfaces)Files.p
- ; $ENDC
-
- ; $IFC UNDEFINED UsingMemory
-
- (require-interface 'MEMORY) ; $I $$Shell(PInterfaces)Memory.p
- ; $ENDC
-
- ; $IFC UNDEFINED UsingTypes
-
- (require-interface 'TYPES) ; $I $$Shell(PInterfaces)Types.p
- ; $ENDC
-
- ; $SETC UsingIncludes:= DigitalSignatureIncludes
-
- ; —————————————————————————— TRAP SELECTORS ——————————————————————————
-
- (defconstant $kSIGNewContext 1900)
- (defconstant $kSIGDisposeContext 1901)
-
- (defconstant $kSIGSignPrepare 1902)
- (defconstant $kSIGSign 1903)
-
- (defconstant $kSIGVerifyPrepare 1904)
- (defconstant $kSIGVerify 1905)
-
- (defconstant $kSIGDigestPrepare 1906)
- (defconstant $kSIGDigest 1907)
-
- (defconstant $kSIGProcessData 1908)
-
- (defconstant $kSIGShowSigner 1909)
- (defconstant $kSIGGetSignerInfo 1910)
- (defconstant $kSIGGetCertInfo 1911)
- (defconstant $kSIGGetCertNameAttributes 1912)
- (defconstant $kSIGGetCertIssuerNameAttributes 1913)
-
- (defconstant $kSIGFileIsSigned 2500)
- (defconstant $kSIGSignFile 2501)
- (defconstant $kSIGVerifyFile 2502)
-
- ; values of SIGNameAttributeType
- (defconstant $kSIGCountryCode 0)
- (defconstant $kSIGOrganization 1)
- (defconstant $kSIGStreetAddress 2)
- (defconstant $kSIGState 3)
- (defconstant $kSIGLocality 4)
- (defconstant $kSIGCommonName 5)
- (defconstant $kSIGTitle 6)
- (defconstant $kSIGOrganizationUnit 7)
- (defconstant $kSIGPostalCode 8)
-
- (def-mactype :SIGNAMEATTRIBUTETYPE (find-mactype :SIGNED-INTEGER))
-
- ;
- ; Certificate status codes returned in SIGCertInfo or SIGSignerInfo from
- ; either SIGGetCertInfo or SIGGetSignerInfo respectively. kSIGValid means that
- ; the certificate is currently valid. kSIGPending means the certificate is
- ; currently not valid - but will be. kSIGExpired means the certificate has
- ; expired. A time is always associated with a SIGCertStatus. In each case the
- ; time has a specific interpretation. When the status is kSIGValid the time is
- ; when the certificate will expire. When the status is kSIGPending the time is
- ; when the certificate will become valid. When the status is kSIGExpired the time
- ; is when the certificate expired. In the SIGCertInfo structure, the startDate
- ; and endDate fields hold the appropriate date information. In the SIGSignerInfo
- ; structure, this information is provided in the certSetStatusTime field. In the
- ; SIGSignerInfo struct, the status time is actually represented by the SIGSignatureStatus
- ; field which can contain any of the types below. NOTE: The only time you will get
- ; a kSIGInvalid status is when it pertains to a SIGSignatureStatus field and only when
- ; you get a signature that was created after the certificates expiration date, something
- ; we are not allowing on the Mac but that may not be restricted on other platforms. Also,
- ; it will not be possible to get a kSIGPending value for SIGSignatureStatus on the Mac but
- ; possibly allowed by other platforms.
- ;
-
- ; Values for SIGCertStatus or SIGSignatureStatus
-
- (defconstant $kSIGValid 0) ; possible for either a SIGCertStatus or SIGSignatureStatus
- (defconstant $kSIGPending 1) ; possible for either a SIGCertStatus or SIGSignatureStatus
- (defconstant $kSIGExpired 2) ; possible for either a SIGCertStatus or SIGSignatureStatus
- (defconstant $kSIGInvalid 3) ; possible only for a SIGSignatureStatus
-
- (def-mactype :SIGCERTSTATUS (find-mactype :SIGNED-INTEGER))
- (def-mactype :SIGSIGNATURESTATUS (find-mactype :SIGNED-INTEGER))
-
- ; Gestalt selector code - returns toolbox version in low-order word
-
- (defconstant $gestaltDigitalSignatureVersion :|dsig|)
-
- ; Number of bytes needed for a digest record when using SIGDigest
- (defconstant $kSIGDigestSize 16)
-
- (def-mactype :SIGDIGESTDATA (find-mactype :ARRAY))
- (def-mactype :SIGDIGESTDATAPTR (find-mactype :POINTER))
-
- (defrecord SIGCertInfo
- (startDate :SIGNED-LONG) ; cert start validity date
- (endDate :SIGNED-LONG) ; cert end validity date
- (certStatus :SIGNED-INTEGER) ; see comment on SIGCertStatus for definition
- (certAttributeCount :SIGNED-LONG); number of name attributes in this cert
- (issuerAttributeCount :SIGNED-LONG); number of name attributes in this certs issuer
- (serialNumber (:STRING 255)) ; cert serial number
- )
-
- (def-mactype :SIGCERTINFOPTR (find-mactype :POINTER))
-
- (defrecord SIGSignerInfo
- (signingTime :SIGNED-LONG) ; time of signing
- (certCount :SIGNED-LONG) ; number of certificates in the cert set
- (certSetStatusTime :SIGNED-LONG); Worst cert status time. See comment on
- ; SIGCertStatus for definition
- (signatureStatus :SIGNED-INTEGER); The status of the signature. See comment on
- ; SIGCertStatus for definition
- )
-
- (def-mactype :SIGSIGNERINFOPTR (find-mactype :POINTER))
-
- (defrecord SIGNameAttributesInfo
- (onNewLevel :BOOLEAN)
- (attributeType :SIGNED-INTEGER)
- (attributeScript :SIGNED-INTEGER)
- (attribute (:STRING 255))
- )
-
- (def-mactype :SIGNAMEATTRIBUTESINFOPTR (find-mactype :POINTER))
-
- (def-mactype :SIGCONTEXTPTR (find-mactype :POINTER))
- (def-mactype :SIGSIGNATUREPTR (find-mactype :POINTER))
-
- ;
- ; Certificates are always in order. That is, the signers cert is always 0, the
- ; issuer of the signers cert is always 1 etc… to the number of certificates-1.
- ; You can use this constant for readability in your code.
- ;
-
- (defconstant $kSIGSignerCertIndex 0)
-
- ;
- ; Call back procedure supplied by developer, return false to cancel the current process.
- ;
-
- (def-mactype :SIGSTATUSPROCPTR (find-mactype :POINTER)); FUNCTION SIGStatusProcPtr(): BOOLEAN;
-
- ;
- ; Resource id of standard signature icon suite, all sizes and colors are available.
- ;
-
- (defconstant $kSIGSignatureIconResID -16797) ; Note that this is the FINAL value for this constant, not the BETA value!
-
- ; ——————————————————————————————— CONTEXT CALLS ———————————————————————————————
- ;
- ; To use the Digital Signature toolbox you will need a SIGContextPtr. To create
- ; a SIGContextPtr you simply call SIGNewContext and it will create and initialize
- ; a context for you. To free the memory occupied by the context and invalidate
- ; its internal data, call SIGDisposeContext. An initialized context has no notion
- ; of the type of operation it will be performing however, once you call
- ; SIGSignPrepare SIGVerifyPrepare, or SIGDigestPrepare, the contexts operation
- ; type is set and to switch to another type of operation will require creating a
- ; new context. Be sure to pass the same context to corresponding toolbox calls
- ; (ie: SIGSignPrepare; SIGProcessData, SIGSign) in other words mixing lets say
- ; signing and verify calls with the same context is not allowed.
- ;
-
-
- (deftrap _signewcontext ((context (:pointer :pointer)))
- (:stack :signed-integer)
- (:stack-trap #xAA5D :d0 (+ (ash 2 16) 1900) context))
-
-
- (deftrap _sigdisposecontext ((context :pointer))
- (:stack :signed-integer)
- (:stack-trap #xAA5D :d0 (+ (ash 2 16) 1901) context))
-
- ; ——————————————————————————————— SIGNING CALLS ———————————————————————————————
- ;
- ; Once you have created a SIGContextPtr, you create a signature by calling
- ; SIGSignPrepare once, followed by n calls to SIGProcessData, followed by one call
- ; to SIGSign. To create another signature on different data but for the same
- ; signer, don't dispose of the context and call SIGProcessData for the new data
- ; followed by a call SIGSign again. In this case the signer will not be prompted
- ; for their signer and password again as it was already provided. Once you call
- ; SIGDisposeContext, all signer information will be cleared out of the context and
- ; the signer will be re-prompted. The signer file FSSpecPtr should be set to nil
- ; if you want the toolbox to use the last signer by default or prompt for a signer
- ; if none exists. The prompt parameter can be used to pass a string to be displayed
- ; in the dialog that prompts the user for their password. If the substring "^1"
- ; (without the quotes) is in the prompt string, then the toolbox will replace it
- ; with the name of the signer from the signer selected by the user. If an empty
- ; string is passed, the following default string will be sent to the toolbox
- ; "\pSigning as ^1.". You can call any of the utility routines after SIGSignPrepare
- ; or SIGSign to get information about the signer or certs.
- ;
-
-
- (deftrap _sigsignprepare ((context :pointer) (signerfile (:pointer :fsspec)) (prompt (:pointer (:string 255))) (signaturesize (:pointer :signed-long)))
- (:stack :signed-integer)
- (:stack-trap #xAA5D :d0 (+ (ash 8 16) 1902) context signerfile prompt signaturesize))
-
-
- (deftrap _sigsign ((context :pointer) (signature :pointer) (statusproc :pointer))
- (:stack :signed-integer)
- (:stack-trap #xAA5D :d0 (+ (ash 6 16) 1903) context signature statusproc))
-
- ; ——————————————————————————————— VERIFYING CALLS ———————————————————————————————
- ;
- ; Once you have created a SIGContextPtr, you verify a signature by calling
- ; SIGVerifyPrepare once, followed by n calls to SIGProcessData, followed by one
- ; call to SIGVerify. Check the return code from SIGVerify to see if the signature
- ; verified or not (noErr is returned on success otherwise the appropriate error
- ; code). Upon successfull verification, you can call any of the utility routines
- ; to find out who signed the data.
- ;
-
-
- (deftrap _sigverifyprepare ((context :pointer) (signature :pointer) (signaturesize :signed-long) (statusproc :pointer))
- (:stack :signed-integer)
- (:stack-trap #xAA5D :d0 (+ (ash 8 16) 1904) context signature signaturesize statusproc))
-
-
- (deftrap _sigverify ((context :pointer))
- (:stack :signed-integer)
- (:stack-trap #xAA5D :d0 (+ (ash 2 16) 1905) context))
-
- ; —————————————————————————————— DIGESTING CALLS ——————————————————————————————
- ;
- ; Once you have created a SIGContextPtr, you create a digest by calling
- ; SIGDigestPrepare once, followed by n calls to SIGProcessData, followed by one
- ; call to SIGDigest. You can dispose of the context after SIGDigest as the
- ; SIGDigestData does not reference back into it. SIGDigest returns the digest in
- ; digest.
- ;
-
-
- (deftrap _sigdigestprepare ((context :pointer))
- (:stack :signed-integer)
- (:stack-trap #xAA5D :d0 (+ (ash 2 16) 1906) context))
-
-
- (deftrap _sigdigest ((context :pointer) (digest (:array :unsigned-byte (- \#$KSIGDIGESTSIZE 1 -1))))
- (:stack :signed-integer)
- (:stack-trap #xAA5D :d0 (+ (ash 4 16) 1907) context digest))
-
- ; —————————————————————————————— PROCESSING DATA ——————————————————————————————
- ;
- ; To process data during a digest, sign, or verify operation call SIGProcessData
- ; as many times as necessary and with any sized blocks of data. The data needs to
- ; be processed in the same order during corresponding sign and verify operations
- ; but does not need to be processed in the same sized chunks (i.e., the toolbox
- ; just sees it as a continuous bit stream).
- ;
-
-
- (deftrap _sigprocessdata ((context :pointer) (data :pointer) (datasize :signed-long))
- (:stack :signed-integer)
- (:stack-trap #xAA5D :d0 (+ (ash 6 16) 1908) context data datasize))
-
- ; ——————————————————————————————— UTILITY CALLS ———————————————————————————————
- ;
- ; Given a context that has successfully performed a verification SIGShowSigner
- ; will display a modal dialog with the entire distinguished name of the person
- ; who signed the data. the prompt (if supplied) will appear at the top of the
- ; dialog. If no prompt is specified, the default prompt "\pVerification
- ; Successfull." will appear.
- ;
- ; Given a context that has been populated by calling SIGSignPrepare, SIGSign or a
- ; successful SIGVerify, you can make the remaining utility calls:
- ;
- ; SIGGetSignerInfo will return the SignerInfo record. The certCount can be used
- ; to index into the certificate set when calling SIGGetCertInfo,
- ; SIGGetCertNameAttributes or SIGGetCertIssuerNameAttributes. The signingTime is
- ; only defined if the call is made after SIGSign or SIGVerify. The certSetStatus
- ; will tell you the best status of the entire certificate set while
- ; certSetStatusTime will correspond to the time associated with that status (see
- ; definitions above).
- ;
- ; SIGGetCertInfo will return the SIGCertInfo record when given a valid index into
- ; the cert set in certIndex. Note: The cert at index kSIGSignerCertIndex is
- ; always the signers certificate. The serial number, start date and end date
- ; are there should you wish to display that info. The certAttributeCount and
- ; issuerAttributeCount provide the number of parts in the name of that certificate
- ; or that certificates issuer respectively. You use these numbers to index into
- ; either SIGGetCertNameAttributes or SIGGetCertIssuerNameAttributes to retrieve
- ; the name. The certStatus will tell you the status of the certificate while
- ; certStatusTime will correspond to the time associated with that status (see
- ; definitions above).
- ;
- ; SIGGetCertNameAttributes and SIGGetCertIssuerNameAttributes return name parts
- ; of the certificate at certIndex and attributeIndex. The newLevel return value
- ; tells you wether the name attribute returned is at the same level in the name
- ; hierarchy as the previous attribute. The type return value tells you the type
- ; of attribute returned. nameAttribute is the actual string containing the name
- ; attribute. So, if you wanted to display the entire distinguished name of the
- ; person who's signature was just validated you could do something like this;
- ;
- ; (…… variable declarations and verification code would preceed this sample ……)
- ;
- ; error = SIGGetCertInfo(verifyContext, kSIGSignerCertIndex, &certInfo);
- ; HandleErr(error);
- ;
- ; for (i = 0; i <= certInfo.certAttributeCount-1; i++)
- ; error = SIGGetCertNameAttributes(verifyContext, kSIGSignerCertIndex, i, &newLevel, &type, theAttribute);
- ; HandleErr(error);
- ; DisplayNamePart(theAttribute, type, newLevel);
- ;
-
-
- (deftrap _sigshowsigner ((context :pointer) (prompt (:pointer (:string 255))))
- (:stack :signed-integer)
- (:stack-trap #xAA5D :d0 (+ (ash 4 16) 1909) context prompt))
-
-
- (deftrap _siggetsignerinfo ((context :pointer) (signerinfo (:pointer :sigsignerinfo)))
- (:stack :signed-integer)
- (:stack-trap #xAA5D :d0 (+ (ash 4 16) 1910) context signerinfo))
-
-
- (deftrap _siggetcertinfo ((context :pointer) (certindex :signed-long) (certinfo (:pointer :sigcertinfo)))
- (:stack :signed-integer)
- (:stack-trap #xAA5D :d0 (+ (ash 6 16) 1911) context certindex certinfo))
-
-
- (deftrap _siggetcertnameattributes ((context :pointer) (certindex :signed-long) (attributeindex :signed-long) (attributeinfo (:pointer :signameattributesinfo)))
- (:stack :signed-integer)
- (:stack-trap #xAA5D :d0 (+ (ash 8 16) 1912) context certindex attributeindex attributeinfo))
-
-
- (deftrap _siggetcertissuernameattributes ((context :pointer) (certindex :signed-long) (attributeindex :signed-long) (attributeinfo (:pointer :signameattributesinfo)))
- (:stack :signed-integer)
- (:stack-trap #xAA5D :d0 (+ (ash 8 16) 1913) context certindex attributeindex attributeinfo))
-
- ; ——————————————————————————— FILE SIGN & VERIFY CALLS ——————————————————————————
- ;
- ; These calls allow you to detect the presence of a standard signtaure in a file as
- ; well as sign and verify files in a standard way. An example of this is the Finder,
- ; which uses these calls to allow the user to "drop sign" a file.
- ;
- ; To detect if a file is signed in the standard way, pass the FSSpec of the file to SIGFileIsSigned.
- ; A result of noErr means the file is in fact signed, otherwise, a kSIGNoSignature error will
- ; be returned.
- ;
- ; Once you have created a SIGContextPtr, you can make calls to either sign or verify a file in
- ; a standard way:
- ;
- ; To sign a file, call SIGSignPrepare followed by 'n' number of calls to SIGSignFile,
- ; passing it the file spec for each file you wish to sign in turn. You supply the context, the signature
- ; size that was returned from SIGSignPrepare and an optional call back proc. The call will take care of all
- ; the processing of data and affixing the signature to the file. If a signature already exists in the file,
- ; it is replaced with the newly created signature.
- ;
- ; To verify a file that was signed using SIGSignFile, call SIGVerifyFile passing it a new context and
- ; the file spec. Once this call has completed, if the verification is successfull, you can pass the context
- ; to SIGShowSigner to display the name of the person who signed the file.
- ;
-
-
- (deftrap _sigfileissigned ((filespec :fsspec))
- (:stack :signed-integer)
- (:stack-trap #xAA5D :d0 (+ (ash 2 16) 2500) filespec))
-
-
- (deftrap _sigsignfile ((context :pointer) (signaturesize :signed-long) (filespec :fsspec) (statusproc :pointer))
- (:stack :signed-integer)
- (:stack-trap #xAA5D :d0 (+ (ash 8 16) 2501) context signaturesize filespec statusproc))
-
-
- (deftrap _sigverifyfile ((context :pointer) (filespec :fsspec) (statusproc :pointer))
- (:stack :signed-integer)
- (:stack-trap #xAA5D :d0 (+ (ash 6 16) 2502) context filespec statusproc))
-
- ; $ENDC ; UsingDigitalSignature
-
- ; $IFC NOT UsingIncludes
-
- ; $ENDC
-
- (export '($KSIGSIGNATUREICONRESID $KSIGSIGNERCERTINDEX $KSIGDIGESTSIZE
- $GESTALTDIGITALSIGNATUREVERSION $KSIGINVALID $KSIGEXPIRED
- $KSIGPENDING $KSIGVALID $KSIGPOSTALCODE $KSIGORGANIZATIONUNIT
- $KSIGTITLE $KSIGCOMMONNAME $KSIGLOCALITY $KSIGSTATE
- $KSIGSTREETADDRESS $KSIGORGANIZATION $KSIGCOUNTRYCODE $KSIGVERIFYFILE
- $KSIGSIGNFILE $KSIGFILEISSIGNED $KSIGGETCERTISSUERNAMEATTRIBUTES
- $KSIGGETCERTNAMEATTRIBUTES $KSIGGETCERTINFO $KSIGGETSIGNERINFO
- $KSIGSHOWSIGNER $KSIGPROCESSDATA $KSIGDIGEST $KSIGDIGESTPREPARE
- $KSIGVERIFY $KSIGVERIFYPREPARE $KSIGSIGN $KSIGSIGNPREPARE
- $KSIGDISPOSECONTEXT $KSIGNEWCONTEXT))
- (provide-interface 'DigitalSignature)